<!-- 
  动态合并单元格
    当表格数据是重复渲染时，需要将数据重复的单元格合并，使表格看起来简明扼要
    table组件有一个方法  span-method可以实现合并行或列，
                        参数是对象，里面包含：row column rowIndex columnIndex 
                        该函数会返回一个包含两个元素的数组 return [rowspan, colspan]
                        其中rowspan代表要合并的行数，colspan代表要合并的列数
                        例如：return [2, 1]就表示：
                                首先要确定当前的rowIndex是多少，
                                以便知道从第rowIndex的单元格数起，
                                以当前这个单元格的rowIndex和columnIndex为起点，合并第一行到第二行的第一列
                        例如：return [1, 2]就表示：
                                首先要确定当前的rowIndex是多少，
                                以便知道从第rowIndex的单元格数起，
                                以当前这个单元格的rowIndex和columnIndex为起点，合并第一行的第一列到第二列
  el-table合并行的思路：
    1、循环所有的数据，利用index，从第二条数据开始，第二条跟第一条比对，第三条跟第二条比对...看数据是否相同
        此种比对具有局限性，因为只能比对相邻数据，倘若相隔几条的数据也有相同的，就不会被合并
    2、若数据相同，设置count+1，并给mergeObj[key]里面push一个0，表示占位当前下标的数据是需要合并的
    3、若数据不同，设置count的值为当前数据的下标，并给mergeObj[key]里面push一个1，待下一个数据与此条相同时，再重复2的操作
    4、上述方法可以得到记录合并行下标的mergeObj，然后利用span-method，先判断哪些列是需要合并的
        mergeObj存放的是  要合并的列名以及每个列名下从下标为0开始要合并的行的个数，不用合并的行下标给0
        rowIndex是当前行下标 判断mergeObj[rowIndex]的值是不是为0
        若不是0，则表示从rowIndex这行开始数起，有 mergeObj[column.property][rowIndex] 个行要合并
        若是0，则表示这样是需要合并的行，return [0, 0]表示不用操作
 -->
<template>
  <general-table
    :tableAttr="tableAttr"
    :data="tableData"
    :columns="columns"
  >
  </general-table>
</template>

<script lang="ts" setup>
import GeneralTable from '@/components/GeneralTable.vue'
import { ref, onMounted } from 'vue'

const tableAttr = {
  border: true,
  spanMethod: ({ row, column, rowIndex, columnIndex }: any) => {
    if(mergeArr.value.indexOf(column.property) !== -1) { 
      if(mergeObj.value[column.property][rowIndex]) { 
        return [mergeObj.value[column.property][rowIndex], 1]
      } else {
        return [0, 0]; 
      }
    }
  }
}

const getSpanArray = (data: any) => {
  mergeArr.value.forEach((key, index1) => {
    let count = 0; // 用来记录需要合并行的起始位置
    mergeObj.value[key] = []; // 记录每一列的合并信息
    data.forEach((item: any, index: number) => {
      if(index === 0) {
        mergeObj.value[key].push(1); 
      } else {
        if(item[key] === data[index - 1][key]) { 
          mergeObj.value[key][count] += 1;    // count=0,所以这句就是指mergeObj.value[key]的下标为0的数据  +=1
          mergeObj.value[key].push(0);
        } else {
          count = index; // 记录当前不相等的行的位置 
          mergeObj.value[key].push(1); // 再重新push 一个 1
        }
      }
    })
  })
}

onMounted(() => {
  getSpanArray(tableData.value);
})

let mergeObj: any = ref({})       // 用来记录需要合并行的下标
let mergeArr = ref(['time', 'grade', 'name', 'subjects', 'score'])     // 需要合并的列名 

const tableData = ref([
  { time: '2020-08-10', grade: '三年二班', name: '小明', subjects: '语文', score: 80 },
 
  { time: '2020-08-10', grade: '三年二班', name: '小明', subjects: '数学', score: 80 },

  { time: '2020-08-10', grade: '三年一班', name: '小雷', subjects: '语文', score: 70 },

  { time: '2020-08-10', grade: '三年一班', name: '小雷', subjects: '数学', score: 80 },

  { time: '2020-08-11', grade: '三年三班', name: '小花', subjects: '语文', score: 60 },

  { time: '2020-08-11', grade: '三年三班', name: '小花', subjects: '数学', score: 60 },
])

const columns = [
  { label: '时间', prop: 'time' },
  { label: '年级', prop: 'grade' },
  { label: '姓名', prop: 'name' },
  { label: '科目', prop: 'subjects' },
  { label: '成绩', prop: 'score' },
]

// const tableData1 = ref([
//   {
//     id: '12987122',
//     name: 'Tom',
//     amount1: '234',
//     amount2: '3.2',
//     amount3: 10,
//   },
//   {
//     id: '12987123',
//     name: 'Tom',
//     amount1: '165',
//     amount2: '4.43',
//     amount3: 12,
//   },
//   {
//     id: '12987124',
//     name: 'Tom',
//     amount1: '324',
//     amount2: '1.9',
//     amount3: 9,
//   },
//   {
//     id: '12987125',
//     name: 'Tom',
//     amount1: '621',
//     amount2: '2.2',
//     amount3: 17,
//   },
//   {
//     id: '12987126',
//     name: 'Tom',
//     amount1: '539',
//     amount2: '4.1',
//     amount3: 15,
//   },
// ])

// const columns1 = [
//   { label: 'id', prop: 'id' },
//   { label: 'name', prop: 'name' },
//   { label: 'amount1', prop: 'amount1' },
//   { label: 'amount2', prop: 'amount2' },
//   { label: 'amount3', prop: 'amount3' },
// ]
 
// // let mergeArr = ref(['id', 'amount1', 'name', 'amount2', 'amount3'])     // 需要合并的列名 



// // 以下是有注释的方法
// const getSpanArr = (data: any) => {
//   mergeArr.value.forEach((key, index1) => {
//     let count = 0; // 用来记录需要合并行的起始位置
//     mergeObj.value[key] = []; // 记录每一列的合并信息
//     /**
//      * mergeObj = {
//      *  time: [],
//      *  grade: [],
//      *  name: [],
//      *  subjects: [],
//      *  score: []
//      * }
//      */
//     data.forEach((item: any, index: number) => {
//       // index == 0表示数据为第一行，直接 push 一个 1
//       if(index === 0) {
//         mergeObj.value[key].push(1); 
//         /**
//          * mergeObj = {
//          *  time: [1],
//          *  grade: [1],
//          *  name: [1],
//          *  subjects: [1],
//          *  score: [1]
//          * }
//          */
//       } else {
//         // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
//         if(item[key] === data[index - 1][key]) { 
//           mergeObj.value[key][count] += 1;    // count=0,所以这句就是指mergeObj.value[key]的下标为0的数据  +=1
//           mergeObj.value[key].push(0);    // 有相等的，先给mergeObj.value[key]中下表为count的数据+1，再在当前数组中push一个0 作为占位，表示可合并
//         } else {
//           // 如果当前行和上一行其值不相等 
//           count = index; // 记录当前不相等的行的位置 
//           mergeObj.value[key].push(1); // 再重新push 一个 1
//         }
//         /**
//          * mergeObj = {
//          *  time: [4, 0, 0, 0, 2, 0],
//          *  grade: [2, 0, 2, 0, 2, 0],
//          *  name: [2, 0, 2, 0, 2, 0],
//          *  subjects: [1, 1, 1, 1, 1, 1],
//          *  score: [2, 0, 1, 1, 2, 0]
//          * }
//          */
//       }
//     })
//   })
// }

// // objectSpanMethod方法
// // 默认接受四个值 { 当前行的值, 当前列的值, 行的下标, 列的下标 }
// const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
//   // 判断是否是需要合并的列
//   if(mergeArr.value.indexOf(column.property) !== -1) { 
//     /**
//      * mergeObj存放的是  要合并的列名以及每个列名下从下标为0开始要合并的行的个数，不用合并的行下标给0
//      * rowIndex是当前行下标 判断mergeObj[rowIndex]的值是不是为0
//      * 若不是0，则表示从rowIndex这行开始数起，有 mergeObj[column.property][rowIndex] 个行要合并
//      * 若是0，则表示这样是需要合并的行，return [0, 0]表示不用操作
//      * */ 
//     if(mergeObj.value[column.property][rowIndex]) { 
//       return [mergeObj.value[column.property][rowIndex], 1]
//     } else {
//       // 如果为0则为需要合并的行  return [0, 0]表示不用操作
//       return [0, 0]; 
//     }
//   }
// }


</script>
